package cn.yywd_123.biliarchiver.utils;

import cn.yywd_123.biliarchiver.account.Session;

import javax.net.ssl.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class HttpsResponse {
	public static final String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36";

	public static HttpsURLConnection openConnection(URL url) throws IOException {
		HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();

		connection.addRequestProperty("Cookie", Session.current.getCookies());
		connection.addRequestProperty("User-Agent", userAgent);
		connection.addRequestProperty("Connection", "Keep-Alive");
		connection.addRequestProperty("Accept", "*/*");
		connection.setRequestProperty("Sec-Fetch-Mode", "no-cors");
//		connection.addRequestProperty("Accept-Encoding", "gzip, deflate, br");
		connection.addRequestProperty("Referer", "https://www.bilibili.com/video/BV1BJ411T7DA");
		connection.setSSLSocketFactory(MyTrustManager.getSocketFactory());

		return connection;
	}

	static String readResponse(HttpsURLConnection connection) throws IOException {
		if (connection.getResponseCode() > 400 || connection.getResponseCode() == -1) return null;

		Map<String, List<String>> header = connection.getHeaderFields();
		if (header.containsKey("Set-Cookie")) {
			Session.current.clearCookie();
			for (String cookie : header.get("Set-Cookie")) {
				Session.current.addCookie(cookie.split(" ", 2)[0]);
			}
		}

		BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
		StringBuilder sb = new StringBuilder();

		try {
			while (true)
				sb.append(Objects.requireNonNull(br.readLine()));
		} catch (NullPointerException e) {
			connection.disconnect();

			return sb.toString();
		}
	}

	public static String GET(String url) {
		Objects.requireNonNull(url);

		try {
			HttpsURLConnection connection = openConnection(new URL(url));

			connection.connect();

			return readResponse(connection);
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(-1);
			return null;
		}
	}

	public static String POST(String url, String data) {
		Objects.requireNonNull(url);
		Objects.requireNonNull(data);

		try {
			HttpsURLConnection connection = openConnection(new URL(url));

			connection.setRequestMethod("POST");
			connection.setDoOutput(true);
			connection.connect();

			PrintWriter out = new PrintWriter(connection.getOutputStream());
			out.print(data);
			out.flush();

			return readResponse(connection);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static class MyTrustManager implements X509TrustManager {
		static SSLSocketFactory socketFactory;

		public static SSLSocketFactory getSocketFactory() {
			if (socketFactory == null) {
				try {
					SSLContext context = SSLContext.getInstance("SSL", "SunJSSE");
					context.init(null, new TrustManager[]{new MyTrustManager()}, new SecureRandom());
					socketFactory = context.getSocketFactory();
				} catch (Exception e) {
					throw new RuntimeException(e);
				}

			}

			return socketFactory;
		}

		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType) {

		}

		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType) {

		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
	}
}
